import React, { Component } from 'react'
import { Form, Input, Icon, Button, message, } from 'antd'
import { Redirect } from 'react-router-dom'

import logo from '../../assets/images/logo.png'
import './login.less'
import { reqLogin } from '../../api'
import memoryUtils from '../../utils/memoryUtils' // 保存用户信息在文件中
import storageUtils from '../../utils/storageUtils' // 保存用户信息在 localStorage

class Login extends Component {


    handleSubmit = (event) => {

        // 阻住事件的默认行为 (阻止点击自动提交)
        event.preventDefault(); 

        // 对所有表单字段进行验证
        this.props.form.validateFields(async (err, values) => {
            // 验证成功
            if (!err) {
                // console.log('提交登陆的 ajax 请求', values);
                // 请求登陆
                const { username, password } = values;

                // 消除回调函数
                // reqLogin(username, password).then(response => {
                //     console.log('成功了', response.data);
                // }).catch(error => {
                //     console.log('失败了', error);
                // })
             
                    const result = await reqLogin(username, password);
                    
                    if (result.status === 0 ) { // 登陆成功
                        // 提示登陆成功
                        message.success('登陆成功');

                        // 2. 传用户信息过去
                        const user = result.data;
                        // 保存在一个文件里面，在 admin 读取出来
                        memoryUtils.user = user; 
                        storageUtils.saveUser(user);

                        // 1. 跳转到管理界面 push(可回退), replace(不可以回退)
                        this.props.history.replace('/');
                        
                        
                    } else  { // 登陆失败
                        // 提示错误信息
                        message.error(result.msg);
                    }
            }else {
                console.log('校验失败!');
            }
        });

        // // 得到 form 对象
        // const form = this.props.form;
        // // 获取表单项的输入数据
        // const values = form.getFieldsValue();
        // console.log('handleSubmit()', values);
    }

    // 对密码自定义验证
    // 1). 必须输入
    // 2). 必须大于等于 4 位
    // 3). 必须小于等于 12 位
    // 4). 必须是英文、数字或下划线组成
    validatePwd = (rule, value, callback) => { // callback 必须被调用，验证提升信息
        // console.log('validatePwd', rule, value);
        if(!value) {
            callback('密码必须输入');
        }else if(!/^[a-zA-Z0-9_]+$/.test(value)) {
            callback('密码必须是英文、数字或下划线组成');
        }else if(value.length<4) {
            callback('密码长度不能小于4位');
        }else if(value.length>12) {
            callback('密码长度不能大于12位');
        }else {
            callback(); // 验证通过
        }
        // callback('xxx'); // 验证失败，并指定提示的文本
    }

    render() {

        // 3. 如果用户已经登陆，自动跳转到管理界面
        const user = memoryUtils.user;
        if (user._id) {
            return <Redirect to='/' />
        } 

        // 得到具有强大功能的 form 对象
        const form = this.props.form;
        const { getFieldDecorator } = form;

        return (
            <div className="login">
                <header className="login-header">
                    <img src={logo} alt="logo"/>
                    <h1>React 项目: 后台管理系统</h1>
                </header>

                <section className="login-content">
                    <h3>用户登陆</h3>
                    <Form onSubmit={this.handleSubmit} className="login-form">
                        <Form.Item>
                            {
                                getFieldDecorator('username', { // 配置对象：属性名是特定的一些名称
                                    // 声明式验证
                                        rules: [
                                            // 用户名 / 密码的的合法性要求
                                            // 1). 必须输入
                                            // 2). 必须大于等于 4 位
                                            // 3). 必须小于等于 12 位
                                            // 4). 必须是英文、数字或下划线组成
                                            { required: true, whitespace: true, message: '请输入用户名' }, // whitespace 忽视空格
                                            { min: 4, message: '用户名至少4位' },
                                            { max: 12, message: '用户名最多12位'},
                                            { pattern: /^[a-zA-Z0-9_]+$/, message: '用户名必须是英文、数字或下划线组成'}
                                        ],
                                        initialValue: 'admin'
                                })(
                                    <Input prefix={<Icon type="user" style={{color: 'rgba(0,0,0,.25)'}}/>}
                                    placeholder=" 用户名"/>
                                )
                            }
                        </Form.Item>
                        
                        <Form.Item>
                            {
                                getFieldDecorator('password', {
                                    rules: [
                                        {
                                            validator: this.validatePwd
                                        }
                                    ]
                                })(
                                    <Input prefix={<Icon type="lock" style={{color: 'rgba(0,0,0,.25)'}}/>}
                                type="password" placeholder=" 密码"/>
                                )
                            }
                        </Form.Item>
                        <Form.Item>
                        <Button type="primary" htmlType="submit" className="login-form-button">
                            登录
                        </Button>
                        </Form.Item>
                    </Form>
                </section>
            </div>
        )
    }
}

/**
 * 1. 高阶函数
 *      1.1 一类特别的函数
 *          a. 接受函数类型的参数
 *          b. 返回值是函数
 *      1.2 常见高阶函数
 *          1.2.1 参数类型的函数的例子
 *              a. 定时器: setTimeout() / setInterval()
 *              b. Promise: Promise(() => {}) / then(value => {}, reason => {})
 *              c. 数组遍历相关的方法: forEach() / filter() / map() / reduce() / find() / findIndex()
 *          1.2.2 返回值是的函数的例子
 *              a. 函数对象的 bind()
 *              b. Form.create()() / getFieldDecorator()()
 * 
 * 2. 高阶组件
 *      2.1 本质是阳刚函数
 *      2.2 接收一个组件(被包装组件), 返回一个新的组件(包装组件), 包装组件会向被包装租价传入特定属性
 *      2.3 作用：扩展组件的功能
 *      2.4 高阶组件也是高阶函数: 接收一个组件函数，返回一个新的组件函数
 * 
*/

// 包装 Form 组件生成一个新的组件: Form(Login)
// 新组建会向 Form 组件传递一个强大的对象属性: form
const WrapLogin = Form.create()(Login)
export default WrapLogin
// 1. 前台表单验证 
// 2. 收集表单输入数据

// async 和 await
    // 作用：简化 promise 对象的使用，不用在使用 then() 来指定成功/失败的回调函数。以同步编码(没有回调函数)方式实现异步流程
    // 那里写 await: 在返回 promise 的表达式左侧写 await， 实现不想要 promise 异步执行的成功的 value 数据
    // 那里写 async: await 所在最近函数定义的左侧写 async